package Infix2RPM.processor.Stack;

import java.util.LinkedList;

import Infix2RPM.processor.Exception.LogicException;

public class RPN {
	public static Object evalRPN(final BasicOperand[] operandArray)
			throws LogicException {
		final LinkedList<BasicOperand> stack = new LinkedList<BasicOperand>();
		System.out.println("Input\tOperation\tStack after");
		for (final BasicOperand token : operandArray) {
			System.out.print(token + "\t");

			if (!token.isNull()) {
				System.out.print("Push\t\t");
				stack.push(token);

			} else if (token.equals("*")) {
				System.out.print("Operate\t\t");
				final BasicOperand secondOperand = stack.pop();
				final BasicOperand firstOperand = stack.pop();
				stack.push(firstOperand.multiply(secondOperand));

			} else if (token.equals("/")) {
				System.out.print("Operate\t\t");
				final BasicOperand secondOperand = stack.pop();
				final BasicOperand firstOperand = stack.pop();
				stack.push(firstOperand.divide(secondOperand));

			} else if (token.equals("-")) {
				System.out.print("Operate\t\t");
				final BasicOperand secondOperand = stack.pop();
				final BasicOperand firstOperand = stack.pop();
				stack.push(firstOperand.subtract(secondOperand));

			} else if (token.equals("+")) {
				System.out.print("Operate\t\t");
				final BasicOperand secondOperand = stack.pop();
				final BasicOperand firstOperand = stack.pop();
				stack.push(firstOperand.add(secondOperand));

			} else if (token.equals("^")) {
				System.out.print("Operate\t\t");
				final BasicOperand secondOperand = stack.pop();
				final BasicOperand firstOperand = stack.pop();
				stack.push(firstOperand.power(secondOperand));

			} else if (token.equals("<")) {
				System.out.print("Operate\t\t");
				final BasicOperand secondOperand = stack.pop();
				final BasicOperand firstOperand = stack.pop();
				stack.push(firstOperand.lessThan(secondOperand));

			} else if (token.equals("<=")) {
				System.out.print("Operate\t\t");
				final BasicOperand secondOperand = stack.pop();
				final BasicOperand firstOperand = stack.pop();
				stack.push(firstOperand.greaterThanEqual(secondOperand));

			} else if (token.equals(">")) {
				System.out.print("Operate\t\t");
				final BasicOperand secondOperand = stack.pop();
				final BasicOperand firstOperand = stack.pop();
				stack.push(firstOperand.greaterThan(secondOperand));

			} else if (token.equals(">=")) {
				System.out.print("Operate\t\t");
				final BasicOperand secondOperand = stack.pop();
				final BasicOperand firstOperand = stack.pop();
				stack.push(firstOperand.greaterThanEqual(secondOperand));

			} else if (token.equals("||")) {
				System.out.print("Operate\t\t");
				final BasicOperand secondOperand = stack.pop();
				final BasicOperand firstOperand = stack.pop();
				stack.push(firstOperand.or(secondOperand));
			
			} else if (token.equals("&&")) {
				System.out.print("Operate\t\t");
				final BasicOperand secondOperand = stack.pop();
				final BasicOperand firstOperand = stack.pop();
				stack.push(firstOperand.and(secondOperand));
			} else {// just in case
				System.out.println("Error");
				return null;
			}
			System.out.println(stack);
		}
		return (stack.pop());
	}
}